#include "game_interface.h"

WindowSettings::WindowSettings()
{
	a_width         = 700;
	a_height        = 700;
	a_viewZoom      = 7.0f;//0.3f;
	a_viewCenter.x  = 0.0f;
	a_viewCenter.y  = 0.0f;
	a_x             = 0;
	a_y             = 0;
	a_w             = 0;
	a_h             = 0;
}

void WindowSettings::modifyViewCenter(b2Vec2 viewCenter)
{
	a_viewCenter = viewCenter;
}

GameScenario* GameInterface::ap_game = NULL;
int32 GameInterface::a_framePeriod = 16;
WindowSettings GameInterface::a_windowSettings;

GameInterface::GameInterface()
{
	ap_game = new GameScenario();
	passViewCenterSettingsToGame();
	initializeGraphics();
}

GameInterface::~GameInterface()
{
	endCurrentGame();
}

void GameInterface::changeGame()
{
	endCurrentGame();
	//TO DO: now set the new game!
}

void GameInterface::initializeGraphics()
{
	int fake_params_count = 1;
	char *fake_params[1];
	fake_params[0] = _strdup("drawer");
	glutInit(&fake_params_count, fake_params);
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
	glutInitWindowSize( a_windowSettings.a_width, a_windowSettings.a_height );
	a_mainWindow  = glutCreateWindow( "box2d" );
	glutDisplayFunc( makeSimulationStep );
    glutAttachMenu( GLUT_RIGHT_BUTTON );
	glutTimerFunc(a_framePeriod, startTimer, a_mainWindow);
	glutKeyboardFunc(processPressKeyboardEvent);
	glutKeyboardUpFunc(processHoldKeyboardEvent);
	GLUI_Master.set_glutReshapeFunc(resizeView); 
	glutMainLoop();
}

void GameInterface::startTimer(int32 mainWindow)
{
	glutSetWindow(mainWindow);
	glutPostRedisplay();
	glutTimerFunc(a_framePeriod, startTimer, mainWindow);
}

void GameInterface::makeSimulationStep()
{
	glClearColor( 0.0, 0.0, 0.0, 0.0 );
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	b2Vec2 old_center = a_windowSettings.a_viewCenter;
	ap_game->makeSimulationStep();
//	if (old_center.x != a_windowSettings.a_viewCenter.x || 
//		old_center.y != a_windowSettings.a_viewCenter.y    )
//	{
		resizeView(a_windowSettings.a_width,
			       a_windowSettings.a_height);
//		printf("lol\n");
//	}
	
	
    
	glFlush();
    glutSwapBuffers();
}

void GameInterface::processPressKeyboardEvent(unsigned char key, int mouseXLocation, int mouseYLocation)
{
	B2_NOT_USED(mouseXLocation);
	B2_NOT_USED(mouseYLocation);

	switch (key)
	{
		case 'z':
			a_windowSettings.a_viewZoom = b2Min(1.1f * a_windowSettings.a_viewZoom, 20.0f);
			resizeView(a_windowSettings.a_width, a_windowSettings.a_height);
			break;
		case 'x':
			a_windowSettings.a_viewZoom = b2Max(0.9f * a_windowSettings.a_viewZoom, 0.02f);
			resizeView(a_windowSettings.a_width, a_windowSettings.a_height);
			break;
		default:
			if (ap_game)
			{
				ap_game->processPressKeyboardEvent(key);
			}
	}
}

void GameInterface::processHoldKeyboardEvent(unsigned char key, int mouseXLocation, int mouseYLocation)
{
	B2_NOT_USED(mouseXLocation);
	B2_NOT_USED(mouseYLocation);

	if (ap_game)
	{
		ap_game->processHoldKeyboardEvent(key);
	}

}

void GameInterface::resizeView(int32 windowWidth, int32 windowHeight)
{
	
	a_windowSettings.a_width = windowWidth;
	a_windowSettings.a_height = windowHeight;

	GLUI_Master.get_viewport_area(
		&a_windowSettings.a_x, 
		&a_windowSettings.a_y,
		&a_windowSettings.a_w, 
		&a_windowSettings.a_h    );
	glViewport(
		a_windowSettings.a_x, 
		a_windowSettings.a_y,
		a_windowSettings.a_w, 
		a_windowSettings.a_h    );

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	float32 ratio = float32(a_windowSettings.a_w) / float32(a_windowSettings.a_h);

	b2Vec2 extents(ratio * 25.0f, 25.0f);
	extents *= a_windowSettings.a_viewZoom;

	b2Vec2 lower = a_windowSettings.a_viewCenter - extents;
	b2Vec2 upper = a_windowSettings.a_viewCenter + extents;

	// L/R/B/T
	gluOrtho2D(lower.x, upper.x, lower.y, upper.y);
}

void GameInterface::endCurrentGame()
{
	delete ap_game;
	ap_game = NULL;
}

void GameInterface::passViewCenterSettingsToGame()
{
	ap_game->connectToViewCenterSettings(a_windowSettings.a_viewCenter);
}